package crond

import (
	"context"
	"device-admin/config/mysql"
	"device-admin/internal/app/grpc/protoc/devicec"
	"device-admin/internal/app/grpc/service/pubsub"
	"device-admin/internal/define"
	"device-admin/internal/models"
	"encoding/base64"
	"encoding/json"
	"strconv"
	"strings"
	"time"

	"192.168.1.75/go-pkg/helper"
	"192.168.1.75/go-pkg/logx"
	"google.golang.org/protobuf/proto"
)

const MaxThemeUpgradeNum = 2

func ThemeUpgrade() {
	logx.Info(context.Background(), "ThemeUpgrade", logx.Any("Start", ""))
	db := mysql.NewDB()
	//处理超时
	db.Model(&models.MaterialThemeTerminals{}).
		Where("upgrade_status = 1").
		Where("updated_at < ?", time.Now().Unix()-180).
		UpdateColumn("upgrade_status", 0)

	//当前正在进行中的设备数
	var UpgradingCount int64
	db.Table(models.MaterialTheme{}.TableName()+" as theme").
		Joins("join "+models.MaterialThemeTerminals{}.TableName()+" as theme_terminals on theme_terminals.theme_id = theme.id").
		Joins("JOIN terminal ON terminal.robot_id = theme_terminals.robot_id AND terminal.terminal_type = theme_terminals.terminal_type").
		Where("terminal.latest_active_time > ?", time.Now().Unix()-60). //在线
		Where("theme_terminals.upgrade_status = 1").                    //同步中
		Count(&UpgradingCount)

	logx.Info(context.Background(), "ThemeUpgrade", logx.Any("UpgradingCount", UpgradingCount))
	if UpgradingCount < int64(MaxThemeUpgradeNum) {
		//灯光资源
		light := define.MaterialLight
		var LightMap = make(map[int]define.LightStruct)
		for _, l := range light {
			LightMap[int(l.ID)] = l
		}
		//获取身份及机器信息
		var ThemeTerminalList = []struct {
			ID                string `json:"id"`
			Name              string `json:"name"`
			MerchantID        string `json:"merchant_id"`
			SoundSource       string `json:"sound_source"`
			IsDefault         int    `json:"is_default"`
			RobotID           string `json:"robot_id"`
			UpgradeType       int32  `json:"upgrade_type"`
			TerminalType      string `json:"terminal_type"`
			PersonalityPrompt string `json:"personality_prompt"`
			Permanent         int    `json:"permanent"`
			StartTime         int64  `json:"start_time"`
			EndTime           int64  `json:"end_time"`
		}{}
		db.Table(models.MaterialTheme{}.TableName()+" as theme").
			Joins("join "+models.MaterialThemeTerminals{}.TableName()+" as theme_terminals on theme_terminals.theme_id = theme.id").
			Joins("JOIN terminal ON terminal.robot_id = theme_terminals.robot_id AND terminal.terminal_type = theme_terminals.terminal_type").
			Where("terminal.latest_active_time > ?", time.Now().Unix()-60).                                                                                                                         //在线
			Where("theme_terminals.upgrade_status = 0 or theme_terminals.upgrade_status = 2 or (theme_terminals.upgrade_status = 3 and theme_terminals.updated_at < ?)", time.Now().Unix()-4*3600). //0 等待同步 2 同步失败 3 推送成功但推送时间已经超过4个小时
			Select("theme.id, theme.name, theme.sound_source, theme.merchant_id, theme.is_default, theme.personality_prompt, theme.permanent, theme.start_time, theme.end_time, theme_terminals.robot_id, theme_terminals.upgrade_type, theme_terminals.terminal_type").
			Order("theme_terminals.updated_at asc").
			Limit(int(MaxThemeUpgradeNum - UpgradingCount)).
			Find(&ThemeTerminalList)

		logx.Info(context.Background(), "ThemeUpgrade", logx.Any("ThemeTerminalList", len(ThemeTerminalList)))
		for _, v := range ThemeTerminalList {

			logx.Info(context.Background(), "ThemeUpgrade", logx.Any("v.ID", v.ID), logx.Any("v.Name", v.Name), logx.Any("v.SoundSource", v.SoundSource), logx.Any("v.PersonalityPrompt", v.PersonalityPrompt), logx.Any("v.UpgradeType", v.UpgradeType))
			reqStartUpgrade := &devicec.ThemeUpgradeV2Req{}
			reqStartUpgrade.Id = v.ID
			reqStartUpgrade.Name = v.Name
			reqStartUpgrade.SoundType = v.SoundSource
			reqStartUpgrade.PersonalityPrompt = v.PersonalityPrompt
			reqStartUpgrade.Permanent = int32(v.Permanent)
			reqStartUpgrade.StartTime = int32(v.StartTime)
			reqStartUpgrade.EndTime = int32(v.EndTime)
			reqStartUpgrade.UpgradeType = v.UpgradeType
			//获取身份对应的所有身份配置
			var ConfigList = []models.MaterialThemeConfig{}
			db.Model(&models.MaterialThemeConfig{}).
				Where("theme_id = ?", v.ID).
				Order("`condition`, voice, emoji, light").
				Find(&ConfigList)
			//获取所有素材信息
			var MaterialList = []models.Material{}
			db.Model(&models.Material{}).
				Where("merchant_id = ?", v.MerchantID).
				Where("audit_status = 1 and status = 1").
				Find(&MaterialList)

			logx.Info(context.Background(), "ThemeUpgrade", logx.Any("v.MerchantID", v.MerchantID), logx.Any("MaterialList", len(MaterialList)))
			var MaterialIDMap = make(map[int]models.Material)
			for _, material := range MaterialList {
				MaterialIDMap[int(material.MaterialID)] = material
			}
			var ThemeConfigList []*devicec.ThemeUpgradeV2Req_ThemeConfig
			for _, configs := range ConfigList {
				//触发条件
				var ConditionConfig = &devicec.ThemeUpgradeV2Req_ThemeConfig{}
				ConditionConfig.Condition = int32(configs.Condition)
				// 语音
				var VoiceConfig = []*devicec.ThemeUpgradeV2Req_VoiceMaterial{}
				for _, voice := range strings.Split(configs.Voice, ",") {
					var voiceItem = &devicec.ThemeUpgradeV2Req_VoiceMaterial{}
					voiceMaterialID, _ := strconv.Atoi(voice)
					if _, ok := MaterialIDMap[voiceMaterialID]; ok {
						voiceItem.Id = int32(voiceMaterialID)
						voiceItem.Name = MaterialIDMap[voiceMaterialID].Name
						voiceItem.Content = MaterialIDMap[voiceMaterialID].Content
						voiceItem.FilePath = MaterialIDMap[voiceMaterialID].FilePath
						if voiceItem.FilePath != "" {
							voiceItem.Md5 = helper.Md5File(voiceItem.FilePath)
						}
					}
					VoiceConfig = append(VoiceConfig, voiceItem)
				}
				ConditionConfig.Voice = VoiceConfig
				// 表情
				var EmojiConfig = []*devicec.ThemeUpgradeV2Req_EmojiMaterial{}
				for _, emoji := range strings.Split(configs.Emoji, ",") {
					var emojiItem = &devicec.ThemeUpgradeV2Req_EmojiMaterial{}
					emojiMaterialID, _ := strconv.Atoi(emoji)
					if _, ok := MaterialIDMap[emojiMaterialID]; ok {
						emojiItem.Id = int32(emojiMaterialID)
						emojiItem.Name = MaterialIDMap[emojiMaterialID].Name
						emojiItem.Content = MaterialIDMap[emojiMaterialID].Content
						emojiItem.FilePath = MaterialIDMap[emojiMaterialID].FilePath
						emojiItem.Md5 = helper.Md5File(emojiItem.FilePath)
					}
					EmojiConfig = append(EmojiConfig, emojiItem)
				}
				ConditionConfig.Emoji = EmojiConfig
				// 灯光
				var LightConfig = []*devicec.ThemeUpgradeV2Req_LightMaterial{}
				for _, light := range strings.Split(configs.Light, ",") {
					var lightItem = &devicec.ThemeUpgradeV2Req_LightMaterial{}
					lightMaterialID, _ := strconv.Atoi(light)
					if _, ok := MaterialIDMap[lightMaterialID]; ok {
						lightItem.Id = int32(lightMaterialID)
						lightItem.Mode = int32(LightMap[lightMaterialID].Mode)
						lightItem.Color = int32(LightMap[lightMaterialID].Color)
						LightConfig = append(LightConfig, lightItem)
					}
				}
				ConditionConfig.Light = LightConfig
				// append
				ThemeConfigList = append(ThemeConfigList, ConditionConfig)
			}
			reqStartUpgrade.Config = ThemeConfigList
			// 修改身份设备表更新时间
			db.Model(&models.MaterialThemeTerminals{}).
				Where("theme_id = ?", reqStartUpgrade.Id).
				Where("robot_id = ? and terminal_type = ?", v.RobotID, v.TerminalType).
				UpdateColumn("updated_at", time.Now().Unix())
			// 发送消息
			sendMsg := &devicec.Msg{}
			sendMsg.Ack = 0
			sendMsg.Seq = helper.RandString(16)
			sendMsg.Name = string(reqStartUpgrade.ProtoReflect().Descriptor().FullName())
			sendMsg.Content, _ = proto.Marshal(reqStartUpgrade)
			contentBytes, _ := json.Marshal(reqStartUpgrade)
			logx.Info(context.Background(), "theme upgrade", logx.Any("device", v.RobotID+"_"+v.TerminalType),
				logx.Any("content", string(contentBytes)))
			// protobuf序列化
			bytes, _ := proto.Marshal(sendMsg)
			pubsub.CMDPublish(v.RobotID, v.TerminalType, "msg", base64.StdEncoding.EncodeToString(bytes))
		}
	}
}
